#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //关闭发送按钮的使能
    ui->sendButton->setEnabled(false);
    ui->label_9->setVisible(false);
    ui->comboBox_2->setVisible(false);
    /* 查找可用的串口 */
    find_seralport();
    /* 查找本地IP地址 */
    find_host_ip();

    index = 0;
    flag = 0;
}

MainWindow::~MainWindow()
{
    if(flag != 0)
    {
        server->close();
        for(int i = 0; i < index; i++)
        {
            clientConnection[i]->disconnectFromHost();/* 使客户端断开连接 */
        }
    }
    delete ui;
}


void MainWindow::on_openPortBtn_clicked()
{
    if(ui->PortBox->isEnabled())
    {
        ui->openPortBtn->setText("关闭");		//按下“OpenPort”后，按键显示为“ClosePort”
        ui->PortBox->setDisabled(true);	//按下“OpenPort”后，禁止再修改COM口
        serial.setPortName(ui->PortBox->currentText());	//设置COM口
        serial.setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);//设置波特率和读写方向
        serial.setDataBits(QSerialPort::Data8);		//数据位为8位
        serial.setFlowControl(QSerialPort::NoFlowControl);//无流控制
        serial.setParity(QSerialPort::NoParity);	//无校验位
        serial.setStopBits(QSerialPort::OneStop);	//一位停止位
        serial.close();					//先关串口，再打开，可以保证串口不被其它函数占用。
        if(serial.open(QIODevice::ReadWrite))		//以可读写的方式打开串口
        {
            connect(&serial,SIGNAL(readyRead()),this,SLOT(read_Com()));	//把串口的readyRead()信号绑定到read_Com()这个槽函数上
        }
        ui->sendButton->setEnabled(true);
    }
    else
    {
        ui->openPortBtn->setText("打开");		//按下“ClosePort”后，按键显示为“OpenPort”
        ui->PortBox->setEnabled(true);		//按下“ClosePort”后，COM口可被修改
        serial.close();					//关串口
        //关闭发送按钮的使能
        ui->sendButton->setEnabled(false);
    }
}


void MainWindow::read_Com()
{
    QByteArray buf;
    /* 信号到来，读取所有的字符串 */
    buf = serial.readAll();
    /* 如果真的有数据 */
    if(!buf.isEmpty())
    {
        QString str = ui->recvTextBrowser->toPlainText();
        str+=tr(buf);
        ui->recvTextBrowser->clear();
        ui->recvTextBrowser->append(str);
    }
    buf.clear();


//    QByteArray temp = serial.readAll();
//      QDataStream out(&temp,QIODevice::ReadWrite);    //将字节数组读入
//      while(!out.atEnd())
//      {
//             qint8 outChar = 0;
//             out>>outChar;   //每字节填充一次，直到结束
//             //十六进制的转换
//             QString str = QString("%1").arg(outChar&0xFF,2,16,QLatin1Char('0'));
//             ui->recvTextBrowser->insertPlainText(str.toUpper());//大写
//             ui->recvTextBrowser->insertPlainText(" ");//每发送两个字符后添加一个空格
//             ui->recvTextBrowser->moveCursor(QTextCursor::End);
//      }

}

void MainWindow::on_sendButton_clicked()
{
    /* 串口发送 */
    serial.write(ui->textEdit_2->toPlainText().toLatin1());
}


/* 查找可用的串口 */
void MainWindow::find_seralport()
{

    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        QSerialPort serial;
        serial.setPort(info);
        if(serial.open(QIODevice::ReadWrite))
        {
            ui->PortBox->addItem(serial.portName());
            serial.close();
        }
    }
}
/* 查找本地IP地址 */
void MainWindow::find_host_ip()
{
    QString str;
    QList<QHostAddress> NetList = QNetworkInterface::allAddresses(); //取得全部信息

    for(int Neti = 0;Neti < NetList.count(); Neti++)
    {
        //排除IPV6，排除回环地址
           if(NetList.at(Neti).protocol() == QAbstractSocket::IPv4Protocol
                   && NetList.at(Neti) != QHostAddress(QHostAddress::LocalHost))
           {

                str = NetList.at(Neti).toString();
                qDebug()<<str;
                if(str.contains("169.254.",Qt::CaseSensitive) == false) //排除掉169.254.这类保留地址
                {
                    if(str.contains(".1",Qt::CaseSensitive) == true)    //排除网关地址
                    {
                        if(str.contains(".1.",Qt::CaseSensitive) == true)
                        {
                            ui->lineEdit_IP->setText(str);
                            ui->lineEdit->setText(str);
                        }
                    }
                    else
                    {
                        ui->lineEdit_IP->setText(str);
                        ui->lineEdit->setText(str);
                    }
                }
           }
    }
}

/* 监听按钮 */
void MainWindow::on_pushButton_Monitor_clicked()
{
    /* UDP */
    if(ui->pushButton_Monitor->text() == "连接" && ui->comboBox->currentIndex() == 0)
    {
        sender = new QUdpSocket(this);

        receiver = new QUdpSocket(this);
        receiver->bind(QHostAddress(ui->lineEdit_IP->text()), ui->lineEdit_Port->text().toInt());
        connect(receiver, SIGNAL(readyRead()), this, SLOT(readUdpDatagrams()));
        ui->pushButton_Monitor->setText("断开");
        ui->comboBox->setEnabled(false);
        ui->lineEdit_IP->setEnabled(false);
        ui->lineEdit_Port->setEnabled(false);
    }
    else if(ui->pushButton_Monitor->text() == "断开" && ui->comboBox->currentIndex() == 0)
    {
        ui->pushButton_Monitor->setText("连接");
        ui->comboBox->setEnabled(true);
        ui->lineEdit_IP->setEnabled(true);
        ui->lineEdit_Port->setEnabled(true);
    }
    /* TCP服务器 */
    if(ui->pushButton_Monitor->text() == "开始监听" && ui->comboBox->currentIndex() == 1)
    {

        server = new QTcpServer();
        qint16 port = ui->lineEdit_Port->text().toInt();
        server->listen(QHostAddress::Any, port);
        connect(server, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
        ui->label_9->setVisible(true);
        ui->comboBox_2->setVisible(true);

        ui->pushButton_Monitor->setText("关闭");

        ui->comboBox->setEnabled(false);
        ui->lineEdit_IP->setEnabled(false);
        ui->lineEdit_Port->setEnabled(false);

        flag = 1;
    }
    else if(ui->pushButton_Monitor->text() == "关闭" && ui->comboBox->currentIndex() == 1)
    {

        server->close();
        for(int i = 0; i < index; i++)
        {
            clientConnection[i]->disconnectFromHost();/* 使客户端断开连接 */
        }
        ui->label_9->setVisible(false);
        ui->comboBox_2->setVisible(false);
        ui->comboBox_2->clear();


        ui->pushButton_Monitor->setText("开始监听");
        ui->comboBox->setEnabled(true);
        ui->lineEdit_IP->setEnabled(true);
        ui->lineEdit_Port->setEnabled(true);
    }
    /* TCP客户端 */
    if(ui->pushButton_Monitor->text() == "连接" && ui->comboBox->currentIndex() == 2)
    {

        client = new QTcpSocket(this);
        client->connectToHost(QHostAddress(ui->lineEdit_IP->text()), ui->lineEdit_Port->text().toInt());
        connect(client, SIGNAL(readyRead()), this, SLOT(readServer()));
        ui->pushButton_Monitor->setText("断开");
        ui->comboBox->setEnabled(false);
        ui->lineEdit_IP->setEnabled(false);
        ui->lineEdit_Port->setEnabled(false);

    }
    else if(ui->pushButton_Monitor->text() == "断开" && ui->comboBox->currentIndex() == 2)
    {
        client->close();
        ui->pushButton_Monitor->setText("连接");
        ui->comboBox->setEnabled(true);
        ui->lineEdit_IP->setEnabled(true);
        ui->lineEdit_Port->setEnabled(true);
    }
}

/* 连接客户端函数 */
void MainWindow::acceptConnection()
{ 

//    connect( &testTimer,SIGNAL(timeout()), this, SLOT(testFunction()) );
//    testTimer.start(1000);
    clientConnection[index] = server->nextPendingConnection();
//    clientConnection[index]->setSocketOption(QAbstractSocket::KeepAliveOption, 1);        //keepAlive
    connect(clientConnection[index], SIGNAL(readyRead()), this, SLOT(readClient()));
    qDebug() << clientConnection[index]->peerAddress().toString();
    qDebug() << clientConnection[index]->peerPort();
//    ui->comboBox_2->setCurrentText(clientConnection->peerAddress().toString() + " : " + QString::number(clientConnection->peerPort()));
//    ui->comboBox_2->addItem();
//    ui->comboBox_2->addItem();
    QIcon a;
    QVariant b;
    QString str = clientConnection[index]->peerAddress().toString() + " : " + QString::number(clientConnection[index]->peerPort());
    str.remove("::ffff:");  //删除多余字符::ffff:
    ui->comboBox_2->addItem(a, str, b); //增加一条客户端信息
    index++;
}

/* 读取客户端数据 */
void MainWindow::readClient()
{
    for(int i = 0; i < index; i++)
    {
        QString str = QString::fromLocal8Bit(clientConnection[i]->readAll());
        if(QString::compare(str, "") == 0)
            continue;
        if(port_old != clientConnection[i]->peerPort())
            str = "【Receive From: " + clientConnection[i]->peerAddress().toString() + " : " + QString::number(clientConnection[i]->peerPort()) + "】: " + str;
        str.remove("::ffff:");  //删除多余字符::ffff:
        qDebug() << str;
        ui->textEdit_NetRecv->append(str);
        port_old = clientConnection[i]->peerPort();
        qDebug() << port_old;
    }

}
/* 读取服务器数据 */
void MainWindow::readServer()
{
    QString str = QString::fromLocal8Bit(client->readAll());
    ui->textEdit_NetRecv->append(str);
}

/* 网络发送按钮 */
void MainWindow::on_pushButton_send_clicked()
{
    /* 网络发送 */
    switch (ui->comboBox->currentIndex())
    {
        case 0:
            serverAddress = QHostAddress(ui->lineEdit->text());
            datagram = ui->textEdit->toPlainText().toLocal8Bit();
            sender->writeDatagram(datagram,serverAddress, ui->lineEdit_2->text().toInt());
        break;

        case 1:
            clientConnection[ui->comboBox_2->currentIndex()]->write(ui->textEdit->toPlainText().toLocal8Bit());
        break;

        case 2:
            client->write(ui->textEdit->toPlainText().toLocal8Bit());
        break;
    }

}

void MainWindow::readUdpDatagrams()
{
    while (receiver->hasPendingDatagrams()) {
            QByteArray datagram;
            datagram.resize(receiver->pendingDatagramSize());
            receiver->readDatagram(datagram.data(), datagram.size());
            //数据接收在datagram里
   /* readDatagram 函数原型
   qint64 readDatagram(char *data,qint64 maxSize,QHostAddress *address=0,quint16 *port=0)
   */
            ui->textEdit_NetRecv->append(datagram.data());
        }

}

/* 清除按钮 */
void MainWindow::on_pushButton_clicked()
{
    ui->textEdit_NetRecv->clear();
}

/* 清除按钮 */
void MainWindow::on_pushButton_2_clicked()
{
    ui->recvTextBrowser->clear();
}

void MainWindow::testFunction()
{
//    qDebug() << clientConnection[0]->read(1);
}

void MainWindow::on_comboBox_currentIndexChanged(int index)
{
    if(index == 2)
        ui->label_8->setText("服务器端口号");
    else
        ui->label_8->setText("本地端口号");

    if(index == 1)
        ui->pushButton_Monitor->setText("开始监听");
    else
        ui->pushButton_Monitor->setText("连接");
}

//int SocketConnected()
//{
//    if(sock<=0)
//        return 0;
//    struct tcp_info info;
//    int len=sizeof(info);
//    getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len);
//    if((info.tcpi_state==TCP_ESTABLISHED))
//    {
//        qDebug() << "socket connected";
//        return 1;
//    }
//    else
//    {
//        qDebug() << "socket disconnected";
//        return 0;
//    }
//}


void MainWindow::StringToHex(QString str, QByteArray &senddata) //字符串转换为十六进制数据0-F
{
    int hexdata,lowhexdata;
    int hexdatalen = 0;
    int len = str.length();
    senddata.resize(len/2);
    char lstr,hstr;

    for(int i=0; i<len; )
    {
        //char lstr,
        hstr=str[i].toLatin1();
        if(hstr == ' ')
        {
            i++;
            continue;
        }
        i++;
        if(i >= len)
            break;
        lstr = str[i].toLatin1();
        hexdata = ConvertHexChar(hstr);
        lowhexdata = ConvertHexChar(lstr);
        if((hexdata == 16) || (lowhexdata == 16))
            break;
        else
            hexdata = hexdata*16+lowhexdata;
        i++;
        senddata[hexdatalen] = (char)hexdata;
        hexdatalen++;
    }
    senddata.resize(hexdatalen);
}

char MainWindow::ConvertHexChar(char ch)
{
    if((ch >= '0') && (ch <= '9'))
        return ch-0x30;
    else if((ch >= 'A') && (ch <= 'F'))
        return ch-'A'+10;
    else if((ch >= 'a') && (ch <= 'f'))
        return ch-'a'+10;
    else return ch-ch;//不在0-f范围内的会发送成0
}
